/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
  <file> uls_istream.h </file>
  <brief>
  	csz: C String terminated by Zero.
    Routines for dynamically manipulating infinite c-string.
    This file is part of ULS, Unified Lexical Scheme.
  </brief>
  <author>
    Stanley J. Hong <babel96@gmail.com>, 2011.
  </author>
*/
#ifndef __CSZ_STREAM_H__
#define __CSZ_STREAM_H__

#include "uls_type.h"

#ifdef __cplusplus
extern "C" {
#endif

#define CSZ_STREAM_DELTA_DFL 128

/* Character Stream Zero */
struct _csz_str {
	uls_char_t     *pool;
	int      pool_size;
	int      alloc_delta;
	int      len;
};

void csz_init(csz_str_t* ss, int n_delta);
#define csz_reset(ss) ((ss)->len = 0)
#define csz_truncate(ss, len2) \
	do { \
		if ((len2) < (ss)->len) (ss)->len = (len2); \
	} while (0)

void csz_deinit(csz_str_t* ss);

uls_char_t* csz_text(csz_str_t* ss);
#define csz_length(s) ((s)->len)
void csz_add_eos(csz_str_t* ss);
void csz_print(csz_str_t* ss);

void csz_putc(csz_str_t* ss, uls_char_t ch);
#define csz_putc_nosafe(s,ch) do { \
		(s)->pool[(s)->len] = (ch); \
		++(s)->len; \
	} while (0)
void csz_puts(csz_str_t* s, uls_char_t* str);
void csz_append(csz_str_t* s, uls_char_t* str, int len);
void csz_modify(csz_str_t* s, int k, uls_char_t* str, int len);

void str_init(uls_char_t** p_outbuf, int* p_outsiz, int siz);
void str_free(uls_char_t** p_outbuf, int* p_outsiz);

void __str_putc(uls_char_t** p_outbuf, int* p_outsiz, int n_delta, int k, uls_char_t ch);
#define str_putc(p_outbuf,p_outsiz,k,ch) \
	__str_putc(p_outbuf, p_outsiz, CSZ_STREAM_DELTA_DFL, k, ch)

#define str_putc_nosafe(p_outbuf, p_outsiz, k, ch) ((*p_outbuf)[k]=(ch))
int  str_puts(uls_char_t** p_outbuf, int* p_outsiz, int k, const uls_char_t* str);
int  str_modify(uls_char_t** p_outbuf, int* p_outsiz, int k, const uls_char_t* str, int len);
#define str_append str_modify
#define str_copy str_modify

void str_free(uls_char_t** p_outbuf, int* p_outsiz);

#ifdef __cplusplus
}
#endif

#endif
